package org.example.batch.util.tools;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import javax.annotation.PostConstruct;
import java.nio.file.Files;
import java.nio.file.Paths;
import java.util.List;

/**
 * 工具类
 *
 * @author hero生仔
 * @date 2025/7/26
 */
@Component
public class ToolsUtil {

    private static int SLEEP_TIME;
    private static int RETRY_TIME;
    private static int OFFSET;
    private static final Logger LOGGER = LoggerFactory.getLogger(ToolsUtil.class);

    @Value("${ter.sleepTime}")
    private int tempSleepTime;

    @Value("${ter.retryTime}")
    private int tempRetryTime;

    @Value("${ter.offset}")
    private int offset;

    // 在依赖注入后执行赋值
    @PostConstruct
    public void init() {
        SLEEP_TIME = tempSleepTime;
        RETRY_TIME = tempRetryTime;
        OFFSET = offset;
    }

    public static JSONArray postUrl(String url, List<JSONObject> jsonObjectList) throws InterruptedException {
        if (jsonObjectList.isEmpty()) {
            return new JSONArray();
        }
        String code = "";
        // 这里不真正请求外部系统，而是读取存量的文件作为返回报文
        JSONObject response = new JSONObject();
        for (int i = 0; i < RETRY_TIME; i++) {
            try {
                String dcsResult;
                // 这里为什么会调用呢？主要是配合返回offset条报文，offset-1条报文，offset-2条报文回去的情况，事实上只需要一个request即可：
                if (OFFSET - jsonObjectList.size() == 1) {
                    dcsResult = requestII(url, jsonObjectList);
                } else if (OFFSET - jsonObjectList.size() == 2) {
                    dcsResult = requestIII(url, jsonObjectList);
                } else {
                    dcsResult = request(url, jsonObjectList);
                }
                response = JSON.parseObject(dcsResult);
                code = response.containsKey("code") ? response.getString("code") : "";
                System.out.println(response.getJSONArray("responseArray"));
                if ("200".equalsIgnoreCase(code)) {
                    break;
                }
            } catch (Exception e) {
                LOGGER.error("调用外部系统失败：url：{}，报文：{}", url, JSONObject.toJSONString(jsonObjectList));
                Thread.sleep(SLEEP_TIME);
            }
        }

        if ("200".equalsIgnoreCase(code)) {
            return response.containsKey("responseArray") ? response.getJSONArray("responseArray") : new JSONArray();
        } else {
            return new JSONArray();
        }
    }

    private static String requestIII(String url, List<JSONObject> jsonObjectList) {
        try {
            // 读取文件内容到字符串（自动处理编码）：准备了多个文件，模拟请求报文每次返回的影响结果不一样。
            return new String(Files.readAllBytes(Paths.get("src/main/resources/response/response3.json")));
        } catch (Exception e) {
            throw new RuntimeException("读取文件失败: " + e.getMessage());
        }
    }

    /**
     * 读取本地文件，模拟请求外部系统获取报文
     *
     * @return 响应报文
     */
    private static String request(String url, List<JSONObject> jsonObjectList) {
        try {
            // 验证重试机制
//            int i = 1 / 0;
            // 读取文件内容到字符串（自动处理编码）：准备了多个文件，模拟请求报文每次返回的影响结果不一样。
            return new String(Files.readAllBytes(Paths.get("src/main/resources/response/response1.json")));
        } catch (Exception e) {
            throw new RuntimeException("读取文件失败: " + e.getMessage());
        }
    }

    private static String requestII(String url, List<JSONObject> jsonObjectList) {
        try {
            // 读取文件内容到字符串（自动处理编码）：准备了多个文件，模拟请求报文每次返回的影响结果不一样。
            return new String(Files.readAllBytes(Paths.get("src/main/resources/response/response2.json")));
        } catch (Exception e) {
            throw new RuntimeException("读取文件失败: " + e.getMessage());
        }
    }
}
